﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using dotsoftRAID_Controller.RAIDControllers;

namespace dotsoftRAID_Controller
{
    public class RAID1 : RAID
    {
        private FileSystemWatcher watcher;
        private string dev0;
        private string dev1;
        private string lastFile;

        public RAID1(string dev0, string dev1)
            : base(dev0, new string[] { dev1 })
        {
            this.dev0 = dev0;
            this.dev1 = dev1;
        }

        public override bool Initialize()
        {
            Logging.EnterMethod();
            ProcessMessage(string.Format("Initializing RAID controller for '{0}' and '{1}' (RAID1)...", this.dev0, this.dev1));

            bool ret = base.Initialize();

            if (ret)
            {
                watcher = new FileSystemWatcher(this.dev0, "*.*");
                watcher.IncludeSubdirectories = true;
                watcher.Changed += ChangeProcess;
                watcher.Created += CreatedProcess;
                watcher.Deleted += DeletedProcess;
                watcher.Renamed += RenamedProcess;
                watcher.EnableRaisingEvents = true;
            }

            Logging.ExitMethod();

            return ret;
        }

        public override void Stop()
        {
            base.Stop();
        }

        protected override void ChangeProcess(object sender, FileSystemEventArgs e)
        {
            ProcessRAID(e);
            base.ChangeProcess(sender, e);
        }

        protected override void CreatedProcess(object sender, FileSystemEventArgs e)
        {
            ProcessRAID(e);
            base.CreatedProcess(sender, e);
        }

        protected override void DeletedProcess(object sender, FileSystemEventArgs e)
        {
            ProcessRAID(e);
            base.DeletedProcess(sender, e);
        }

        protected override void RenamedProcess(object sender, RenamedEventArgs e)
        {
            ProcessRAID(e);
            base.RenamedProcess(sender, e);
        }

        protected override void ProcessRAID(FileSystemEventArgs args)
        {
            Logging.EnterMethod();
            string pathToRAID = BuildPathToRAIDSystem(args.FullPath, this.dev1);

            CreateDirectories(pathToRAID);

            switch (args.ChangeType)
            {
                case WatcherChangeTypes.All:
                    break;
                case WatcherChangeTypes.Changed:
                    if (IsFile(args.FullPath))
                    {
                        if (!File.Exists(pathToRAID))
                        {
                            File.Create(pathToRAID).Close();
                            lastFile = pathToRAID;
                        }
                        else
                        {
                            CopyFile(args.FullPath, pathToRAID);
                        }
                    }
                    break;
                case WatcherChangeTypes.Created:
                    if (IsFile(args.FullPath) && lastFile != pathToRAID)
                    {
                        File.Create(pathToRAID).Close();
                        lastFile = pathToRAID;
                    }
                    else
                    {
                        Directory.CreateDirectory(pathToRAID);
                    }
                    break;
                case WatcherChangeTypes.Deleted:
                    if (IsFile(args.FullPath))
                    {
                        File.Delete(pathToRAID);
                    }
                    else
                    {
                        Directory.Delete(pathToRAID);
                    }
                    break;
                case WatcherChangeTypes.Renamed:
                    RenamedEventArgs renamedArgs = (RenamedEventArgs)args;
                    RenameFileOrDir(BuildPathToRAIDSystem(renamedArgs.OldFullPath, this.dev1), pathToRAID);
                    break;
            }

            Logging.ExitMethod();
        }
    }
}
